package DataStuctures.BST;
import java.util.LinkedList;
import java.util.Queue;

/**
 * 二叉树的层序遍历
 *
 * @param <E>
 */
public class BST_Level_Order<E extends Comparable<E>> {
    //类型E要具有可比较性

    private class Node{
        public E e;
        public Node left,right;

        public Node(E e) {
            this.e = e;
            left = null;
            right = null;
        }
    }

    private Node root;
    private int size;

    public BST_Level_Order() {
        root = null;
        size = 0;
    }

    public int size(){
        return size;
    }

    public boolean isEmpty(){
        return size == 0;
    }


    //向二分搜索树中添加新的元素
    public void add(E e){
        root = add (root,e);
    }

    //向以node为根的二分搜索树中插入元素e，递归算法
    //返回插入新节点后二分搜索树的根
    private Node add(Node node,E e){

        if (node == null) {
            size ++;
            return new Node(e);
        }

        //大于为正 小于为负
        if (e.compareTo(node.e) < 0) {
            node.left = add(node.left,e);
        }else if(e.compareTo(node.e) > 0) {
            node.right = add(node.right,e);
        }
        return node;
    }

    //看二分搜索树中是否包含元素e
    public boolean contains(E e){
        return contains(root,e);
    }

    //看以node为根的二分搜索树中是否包含元素e，递归算法
    private boolean contains(Node node,E e){

        if(node == null){
            return false;
        }

        if(e.compareTo(node.e) == 0){
            return true;
        }else if(e.compareTo(node.e) < 0){
            return contains(node.left,e);
        }else {
            return contains(node.right,e);
        }
    }


    //二分搜索树的层序遍历
    public void levelOrder(){
        Queue<Node> q = new LinkedList<>();
        q.add(root);
        while (!q.isEmpty()) {

            Node cur = q.remove();
            System.out.println(cur.e);

            if (cur.left!=null) {
                q.add(cur.left);
            }
            if (cur.right!=null) {
                q.add(cur.right);
            }
        }
    }


    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        generateBSTString(root,0,res);
        return res.toString();
    }

    private void generateBSTString(Node node,int depth,StringBuilder res){

        if(node == null){
            res.append(generateDepthString(depth) + "null\n");
            return ;
        }
        res.append(generateDepthString(depth) + "null\n");
        generateBSTString(node.left, depth + 1,res);
        generateBSTString(node.right, depth + 1,res);

    }

    private String generateDepthString(int depth){
        StringBuilder res = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            res.append("---");
        }
        return res.toString();
    }

}
